﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using CoreLibrary.Cache;
using CoreLibrary.Repo;
using Entities.DataBase.Obj;
using Entities.DataBase.Persistent;

namespace Entities.DataBase.Impl {

    public class SettingRepository : BaseRepository<Setting>, ISettingRepository {

        private static readonly Func<DataContext, string, Setting>
            LinqGetSettingByName = CompiledQuery.Compile((DataContext context, string name)
                => context.GetTable<Setting>().SingleOrDefault(p => p.Name.Equals(name)));

        private static readonly Func<DataContext, string, Setting>
            LinqGetSettingByCName = CompiledQuery.Compile((DataContext context, string cname)
                => context.GetTable<Setting>().SingleOrDefault(p => p.CName.Equals(cname)));

        public override string TableName {
            get { return "D_SETTING"; }
        }

        public ICache Cache { get; set; }

        public List<Setting> List() {
            return Execute(context => context.GetTable<Setting>().ToList());
        }

        public void Update(SettingKey key, string value) {
            Execute((context, ts) => {
                var setting = LinqGetSettingByName(context,key.Name);
                setting.Value = value;
                setting.DateUpdated = DateTime.UtcNow;
                context.SubmitChanges();
                ts.Complete();
            });
        }

        public void UpdateSettings(List<KeyValuePair<string, string>> values) {
            Execute((context, ts) => {
                foreach (var keyValuePair in values) {
                    var setting = LinqGetSettingByName(context, keyValuePair.Key);
                    if (setting != null && !setting.Value.Equals(keyValuePair.Value)) {
                        setting.Value = keyValuePair.Value;
                        setting.DateUpdated = DateTime.UtcNow;
                    }
                }
                context.SubmitChanges();
                ts.Complete();
            });
        }

        public Setting Get(SettingKey key) {
            return Execute(context => LinqGetSettingByName(context, key.Name));
        }

        public void Add(Setting setting) {
            Execute((context, ts) => {
                var exist = LinqGetSettingByName(context, setting.Name);
                if (exist != null) {
                    throw new Exception("This setting already exist");
                }

                exist = LinqGetSettingByCName(context, setting.CName);
                if (exist != null) {
                    throw new Exception("This setting already exist");
                }

                context.GetTable<Setting>().InsertOnSubmit(setting);
                context.SubmitChanges();
                ts.Complete();
            });
        }

    }
}